// gegevens van upclive.nl ophalen
//
#include <stdio.h>
#include <curl/curl.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <sys/types.h>
#include <pthread.h>
#include "alg.h"
#include "cache.h"
#include "imdb.h"

extern pthread_mutex_t mymutex;
// Teller connecties
extern int maxconn;
extern int mconnect;
//--quiet
extern int stil;
// (default)aantal dagen om te grabben: --days
extern int days;
// --offset
extern int offset;
// --cache
extern short cache;
extern FILE *cachefp;
extern FILE *cachetmp;
// TimeZone
extern short tz;		// Nederland = +0100 (wintertijd, zomertijd = +0200)
// zenderlogo's, default is  niet ophalen.
extern short icon;
extern short imdb;
extern short imdbdirty;
extern int aantalimdb;
//tellertjes
extern unsigned long aantalprog;
extern unsigned long aantalcache;
// systeem jaar, maand, dag.
extern int sys_jaar;
extern int sys_maand;
extern int sys_dag;
extern int sys_wdag;

// Teller connecties omroepgids
int maxconn_upc = 0;
int upctimeout = 10;		//UPC is erg langzaam en geeft veel timeouts, waarde wat korter gezet voor upc.
char *filmtitels[1000];

// Films in gids staan op subcategorie en niet op Speelfilm
// Zoekfunctie van upclive gebruiken om te checken of ik een speelfilm
// heb. voor de hele week de films van een zender 
short vind_film(char *zender, char *timescope)
{
//url
//http://www.upclive.nl/Televisie/TV_gids/Zoek_in_TV_gids/Zoekresultaten/?channels=RTL+7&genre=Speelfilm&subgenre=*&search=&timescope=nextsevendays_all
	CURL *filmhandle;
	int ptr, tel;
	char *urlzender;
	char filmurl[256];
	char buf[1024];
	char *p1, *p2;
	char curlerr[CURL_ERROR_SIZE];
	FILE *filmvind;
	char ftemplate[] = "/tmp/vindfilm_XXXXXX";
	if (!(filmhandle = curl_easy_init()))
		return (0);
	ptr = mkstemp(ftemplate);
	if (ptr == -1)
		return (0);
	filmvind = fdopen(ptr, "w+");
	if (filmvind == 0)
		return (0);

	urlzender = malloc((strlen(zender) + 40) * sizeof(char));
	if (!urlzender)
		return (0);
	strcpy(urlzender, zender);
	chartochar(urlzender, ' ', '+');

	sprintf(filmurl,
		"http://www.upclive.nl/Televisie/TV_gids/Zoek_in_TV_gids/Zoekresultaten/?channels=%s&genre=Speelfilm&subgenre=*&search=&timescope=%s_all",
		urlzender, timescope);
	curl_easy_setopt(filmhandle, CURLOPT_NOSIGNAL, 1);
	curl_easy_setopt(filmhandle, CURLOPT_AUTOREFERER, 1);
	curl_easy_setopt(filmhandle, CURLOPT_FOLLOWLOCATION, 1);
	curl_easy_setopt(filmhandle, CURLOPT_MAXREDIRS, 5);
	curl_easy_setopt(filmhandle, CURLOPT_WRITEDATA, filmvind);
	curl_easy_setopt(filmhandle, CURLOPT_ERRORBUFFER, curlerr);
	curl_easy_setopt(filmhandle, CURLOPT_TIMEOUT, TIMEOUT);
	curl_easy_setopt(filmhandle, CURLOPT_URL, filmurl);
	if (!stil)
		fprintf(stderr, "Ophalen filmtitels %s van %s:\n\t%s\n",
			zender, timescope, filmurl);
	if (curl_easy_perform(filmhandle)) {
		if (!stil)
			fprintf(stderr,
				"Error online films vinden: '%s'\n",
				curlerr);
		curl_easy_cleanup(filmhandle);
		fclose(filmvind);
		unlink(ftemplate);
		return (0);;
	}
	rewind(filmvind);
	for (tel = 0; filmtitels[tel]; tel++);
	int ok = 0;
	rewind(filmvind);
	while (fgets(buf, 1023, filmvind)) {
		p1 = strchr(buf, '<');
		if (!p1)
			continue;

		if (!strncmp
		    (p1, "<div class=\"epg_search_listings\">", 33))
			ok = 1;
		if (!strncmp(p1, "<div class=\"col1\">", 18) && ok) {
			fgets(buf, 1023, filmvind);
			p1 = strchr(buf, '<');
			if (!p1)
				continue;
			p1 += 4;
			p2 = strchr(p1, '<');
			if (!p2)
				continue;
			*p2 = '\0';
			filmtitels[tel] = strdup(p1);
			tel++;
		}
	}
	filmtitels[tel] = NULL;

	fclose(filmvind);
	unlink(ftemplate);
	//fprintf(stderr, "Filmvind %s\n", ftemplate);
	//for(tel=0;filmtitels[tel];tel++)
	//      fprintf(stderr, "Filmtitel %s\n", filmtitels[tel]);
	curl_easy_cleanup(filmhandle);
	return (1);;
}

short getchan_upc(void)
{
	extern channel channelsconf2[];
	//extern channel channels[];
	CURL *handle;
	char curlerror[CURL_ERROR_SIZE];
	char buffer[6000];
	char url[255];
	//char urlicon[255];
	int tmpptr;
	size_t groot;
	int tel = 0;
	int telchar;
	int telchar2;
	char *p1, *p2, *p3;
	FILE *tempfile;
	char template[] = "/tmp/chan_XXXXXX";
	if (!(handle = curl_easy_init()))
		return (0);
	tmpptr = mkstemp(template);
	if (tmpptr == -1)
		return (0);
	tempfile = fdopen(tmpptr, "w+");
	if (tempfile == NULL)
		return (0);
	//curl_easy_setopt(handle, CURLOPT_USERAGENT, "'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)");
	curl_easy_setopt(handle, CURLOPT_NOSIGNAL, 1);
	//curl_easy_setopt(handle, CURLOPT_VERBOSE, 1);
	curl_easy_setopt(handle, CURLOPT_AUTOREFERER, 1);
	curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1);
	curl_easy_setopt(handle, CURLOPT_MAXREDIRS, 5);
	curl_easy_setopt(handle, CURLOPT_WRITEDATA, tempfile);
	curl_easy_setopt(handle, CURLOPT_ERRORBUFFER, curlerror);
	curl_easy_setopt(handle, CURLOPT_TIMEOUT, TIMEOUT);


	fprintf(stderr, "Ophalen zenders van upclive, momentje a.u.b.\n");
	//sprintf(url, "http://tvgids.upc.nl/TV/Guide");
	//sprintf(url, "www.upc.nl/televisie/tv-zenders/");
	sprintf(url, "http://tvgids.upc.nl/TV/wa/grid/?startDateTime=");
	curl_easy_setopt(handle, CURLOPT_URL, url);
	if (curl_easy_perform(handle)) {
		fprintf(stderr, "Error online channelconfig: '%s'\n",
			curlerror);
		fclose(tempfile);
		unlink(template);
		return (0);
	}
	//curl_easy_cleanup(handle);
	rewind(tempfile);
	while (fgets(buffer, 6000, tempfile)) {
		p3 = &buffer[0];
		//while (p1 = strstr(p3, "<div class=\"zender\">")) {
		while (p1 = strstr(p3, "<a class=\"channel_logo\" title=\"")) {
			p3 = p1++;
			p2 = strstr(p1, "title=\"");
			if(! p2 ) {
				continue;
			}
		
			p1 = strchr(p2, '"');
			if(! p1)
				continue;
			
			p1++;
			p2 = strchr(p1, '"');	
			if(! p2 ) {
				continue;
			}
			*p2 = '\0';
			p3 = ++p2;
				
			if(!strcmp(p1, "Lokale Zenders") || ! strcmp (p1, "Regionaal Commerciele Zenders"))
				continue;
			channelsconf2[tel].omschrijving = strdup(p1);
			for (telchar = 0; p1[telchar] != '\0'; telchar++) {
				switch (p1[telchar]) {
				case '/':
					p1[telchar] = '\\';
					break;
				case ' ':
					p1[telchar] = '+';
					break;
				default:
					break;
				}
			}
			groot = (strlen(p1) + 20) * sizeof(char);
			if (strchr(p1, '&')) {
				channelsconf2[tel].id = malloc(groot);
				telchar2 = 0;
				for (telchar = 0; p1[telchar] != '\0';
				     telchar++) {
					switch (p1[telchar]) {
					case '&':
						if (!strncmp
						    (&p1[telchar], "&amp;",
						     4)) {
							channelsconf2[tel].
							    id[telchar2] =
							    '%';
							telchar2++;
							channelsconf2[tel].
							    id[telchar2] =
							    '2';
							telchar2++;
							channelsconf2[tel].
							    id[telchar2] =
							    '6';
							telchar2++;
							telchar += 4;
						} else
							channelsconf2[tel].
							    id[telchar2] =
							    p1[telchar];
						break;
					default:
						channelsconf2[tel].
						    id[telchar2] =
						    p1[telchar];
						telchar2++;
						break;
					}
				}
				channelsconf2[tel].id[telchar2] = '\0';
			} else
				channelsconf2[tel].id = strdup(p1);
			channelsconf2[tel].provider = 1;
			tel++;
		}
	}




/*
		if (!strncmp
		    (p1, "<a href=\"/Televisie/TV_gids/Zenders/", 36)) {
			p1++;
			p2 = strchr(p1, '<');
			p2++;
			p1 = strchr(p2, '/');
			p2 = strchr(p1, '"');
			if (!p1 || !p2)
				continue;
			*p2 = '\0';
			groot = (strlen(p1) + 50) * sizeof(char);
			channelsconf2[tel].icon = (char *) malloc(groot);
			sprintf(channelsconf2[tel].icon,
				"http://www.upclive.nl%s", p1);
		}

*/
	if (tel > 0) {
		channelsconf2[tel].id = NULL;
		channelsconf2[tel].omschrijving = "";
	}
	fclose(tempfile);
	fprintf(stderr, "%d zenders gevonden.\n", tel - 1);
	unlink(template);
	//fprintf(stderr, "template %s\n", template);
	return (tel);
}

int upclive_nl(channel * kanaal)
{
	//urlvoorbeeld
	//http://www.upclive.nl/Televisie/TV_gids/Zenders/Algemeen/Gids/?channels=Nederland+1&timescope=today_all
	CURL *handle;
	char curlerror[CURL_ERROR_SIZE];
	char buffer[1024];
	char buffer2[1024];
	char *buffer3;
	char url[255];
	//long curly;           //voor http errorcode
	long position;
	char cacheid[255];
	char dagdeel;
	int tmpptr;
	int ret, tel, tel2;
	short dagtel = 0;	//0 en 1 is today/tomorrow
	//short dagtel_vorig = 0;
	//short nieuwedag = 0;
	short init = 1;
	short dag2 = sys_wdag + offset;
	char *p, *url_chan, *p2;
	char *pp1, *pp2, *pp3, *pp4, *pp5;
	FILE *tempfile;
	FILE *tempfile2;
	char template[] = "/tmp/grab_XXXXXX";
	char template2[] = "/tmp/grab_XXXXXX";
	char startdatum[9];
	char progstart[20];
	char progstop[20];
	char stopdatum[9];
	short tzone = tz, tzone2 = tz;
	char titel[256] = "";
	char genre[50];
	char *description = NULL;
	char stars[10];
	char date[5];
	time_t progtijd;
	stars[0] = '\0';
	date[0] = '\0';
	date[4] = '\0';

	char *dagje[9];
	dagje[0] = "Sunday";
	dagje[1] = "Monday";
	dagje[2] = "Tuesday";
	dagje[3] = "Wednesday";
	dagje[4] = "Thursday";
	dagje[5] = "Friday";
	dagje[6] = "Saturday";
	dagje[7] = "Today";
	dagje[8] = "Tomorrow";
	if (!(handle = curl_easy_init()))
		return (0);
	tmpptr = mkstemp(template);
	if (tmpptr == -1)
		return (0);
	tempfile = fdopen(tmpptr, "w+");
	if (tempfile == NULL)
		return (0);
	tmpptr = mkstemp(template2);
	if (tmpptr == -1)
		return (0);
	tempfile2 = fdopen(tmpptr, "w+");
	if (tempfile2 == NULL)
		return (0);
	curl_easy_setopt(handle, CURLOPT_NOSIGNAL, 1);
	//curl_easy_setopt(handle, CURLOPT_VERBOSE, 1);
	curl_easy_setopt(handle, CURLOPT_AUTOREFERER, 1);
	curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1);
	curl_easy_setopt(handle, CURLOPT_MAXREDIRS, 5);
	curl_easy_setopt(handle, CURLOPT_WRITEDATA, tempfile);
	curl_easy_setopt(handle, CURLOPT_ERRORBUFFER, curlerror);
	curl_easy_setopt(handle, CURLOPT_TIMEOUT, upctimeout);

	url_chan =
	    (char *) malloc(strlen(kanaal->id) * sizeof(char) + 100);
	if (!url_chan) {
		if (!stil)
			fprintf(stderr,
				"Kan geen geheugen alloceren, ...abort.\n");
		fclose(tempfile);
		unlink(template);
		return (0);
	}

	while (days > dagtel) {
		makedate(sys_jaar, sys_maand, sys_dag + dagtel + offset,
			 12, 0, startdatum, tzone, 0);
		if (cache) {
			sprintf(cacheid, "%s-%s", kanaal->id, startdatum);
			if (vind_cache(cacheid, '1') != -1) {
				pthread_mutex_lock(&mymutex);
				rewind(cachefp);
				while (fgets(buffer, 1023, cachefp)) {
					if (buffer[1] != '1')
						continue;
					if (!strncmp
					    (buffer + 3, cacheid,
					     strlen(cacheid))) {
						aantalcache++;
						p = strchr(buffer + 3,
							   '');
						p++;
						printf("%s", p);
						while (fgets
						       (buffer, 1023,
							cachefp)) {
							if (buffer[0] ==
							    '')
								break;
							printf("%s",
							       buffer);
						}
					}
				}
				pthread_mutex_unlock(&mymutex);
				fflush(NULL);
				dagtel++;
				continue;
			}
		}
		fprintf(tempfile, "\n%s\n", startdatum);
		if (dagtel + offset >= MAXDAYS)
			break;
		if (dagtel + offset < 2) {
			sprintf(url,
				"http://tvgids.upc.nl/TV/Guide/Channel/%s/%s/",
				//"http://www.upclive.nl/Televisie/TV_gids/Zenders/%s/Gids/?channels=%s&theme=All&timescope=%s_all",
				kanaal->id, dagje[dagtel + 7 + offset]);
			//vind_film(kanaal->omschrijving,
			//        dagje[dagtel + 7 + offset]);
		} else {
			if (dag2 > 6)
				dag2 -= 7;
			sprintf(url,
				"http://tvgids.upc.nl/TV/Guide/Channel/%s/%s/",
				//"http://www.upclive.nl/Televisie/TV_gids/Zenders/%s/Gids/?channels=%s&theme=All&timescope=%s_all",
				kanaal->id, dagje[dag2]);
			//vind_film(kanaal->omschrijving, dagje[dag2]);
		}
		if (!stil)
			fprintf(stderr, "Ophalen %s:\n\t%s\n",
				kanaal->omschrijving, url);
		curl_easy_setopt(handle, CURLOPT_URL, url);
		while (maxconn_upc >= mconnect)
			sleep(1);
		pthread_mutex_lock(&mymutex);
		maxconn_upc++;
		pthread_mutex_unlock(&mymutex);
		ret = curl_easy_perform(handle);
		position = ftell(tempfile);
		for (tel = 0; ret && tel < 3; tel++) {
			fprintf(stderr,
				"Error ophalen %s: %s\n\t%s ,...retrying\n",
				kanaal->omschrijving, url, curlerror);
			ret = curl_easy_perform(handle);
			fseek(tempfile, position, SEEK_SET);
		}
		if (ret)
			fprintf(stderr,
				"Error MAXRETRY ophalen %s: %s ,...abort:\t\n%s\n",
				kanaal->omschrijving, url, curlerror);

		dagtel++;
		dag2++;
		pthread_mutex_lock(&mymutex);
		maxconn_upc--;
		pthread_mutex_unlock(&mymutex);
/* misschien ooit implementeren....
		curly = 0;
		if(curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &curly) == CURLE_OK )
		{
		//http response is NIET OK, stoppen met verder ophalen
			if( curly != 200 )
				break;
		}
*/
	}

	curl_easy_setopt(handle, CURLOPT_WRITEDATA, tempfile2);
	dagtel = 0;
	tel = 0;
	rewind(tempfile);
	long pos;
	short tocache;
	char uurtje;
	//wachten op usable imdb
	while (imdbdirty && imdb)
		sleep(3);
	while (fgets(buffer, 1023, tempfile)) {
		url[0] = '\0';

		//Tag programma
		if (strstr(buffer, "<td class=\"event-name\"")) {

			p2 = strrchr(buffer, 'Z');
			if (!p2)
				continue;
			*p2 = '\0';
			p = strrchr(buffer, '_');
			if (!p)
				continue;
			p++;
			pp1 = strtok_r(p, "-T:", &buffer3);
			pp2 = strtok_r(NULL, "-T:", &buffer3);
			pp3 = strtok_r(NULL, "-T:", &buffer3);
			pp4 = strtok_r(NULL, "-T:", &buffer3);
			pp5 = strtok_r(NULL, "-T:", &buffer3);
			if (!pp5) {
				progtijd = 0;
				strcpy(progstop, "000000000000000");
			} else {
				progtijd =
				    makedate(atoi(pp1), atoi(pp2),
					     atoi(pp3), atoi(pp4),
					     atoi(pp5), progstop, tzone,
					     0);
				progtijd += tz * 3600;
				makedate(0, 0, 0, 0, 0, progstop, tzone,
					 progtijd);
			}

			pthread_mutex_lock(&mymutex);
			if (tel) {	//printen als we op de volgende zitten, progstart volgend is progstop vorig
				aantalprog++;
				printf
				    ("<programme start=\"%s +0%d00\" stop=\"%s +0%d00\" channel=\"%s.upclive.nl\">\n",
				     progstart, tzone, progstop, tzone,
				     kanaal->id);
				printf
				    ("   <title lang=\"nl\">%s</title>\n",
				     titel);
				if (description) {
					printf("   <desc lang=\"nl\">%s\n",
					       description);
					printf("   </desc>\n");
					free(description);
					description = NULL;
				}
				printf("   <category>%s</category>\n",
				       genre);
				if (date[0] != '\0')
					printf("   <date>%s</date>\n",
					       date);
				if (stars[0] != '\0')
					printf
					    ("   <star-rating>\n    <value>%s/10</value>\n   </star-rating>\n",
					     stars);
				printf(" </programme>\n");
				// resetten
				stars[0] = '\0';
				date[0] = '\0';
				titel[0] = '\0';
				genre[0] = '\0';
			}
			strcpy(progstart, progstop);

			fflush(NULL);
			pthread_mutex_unlock(&mymutex);

			while (fgets(buffer, 1023, tempfile)) {
				if (strstr(buffer, "</span>") ||
				    strstr(buffer, "</tbody>"))
					break;
				//titel
				if (strstr(buffer, "<a href=")) {
					p = strchr(buffer, '>');
					p++;
					p2 = strrchr(buffer, '<');
					*p2 = '\0';
					strcpy(titel, p);
					conv_char(titel);
					//detail:
					p = strchr(buffer, '"');
					p++;
					p2 = strchr(p, '"');
					*p2 = '\0';
					rewind(tempfile2);
					sprintf(url,
						"http://tvgids.upc.nl%s",
						p);
					curl_easy_setopt(handle,
							 CURLOPT_URL, url);
					while (maxconn_upc >= mconnect)
						sleep(1);
					pthread_mutex_lock(&mymutex);
					maxconn_upc++;
					pthread_mutex_unlock(&mymutex);
					ret = curl_easy_perform(handle);
					for (tel = 0; ret && tel < 3;
					     tel++) {
						if (!stil)
							fprintf(stderr,
								"Error ophalen detailinfo %s; %s ,...retrying\n",
								url,
								curlerror);
						ret =
						    curl_easy_perform
						    (handle);
					}
					if (ret)
						fprintf(stderr,
							"Error MAXRETRY ophalen detailinfo %s,...abort:\t\n%s\n",
							url, curlerror);
					pthread_mutex_lock(&mymutex);
					maxconn_upc--;
					pthread_mutex_unlock(&mymutex);
					if (!ret) {
						rewind(tempfile2);
						while (fgets
						       (buffer2, 1023,
							tempfile2)) {
							if (strstr
							    (buffer2,
							     "program-desc-text")
							    == NULL)
								continue;
							fgets(buffer2,
							      1023,
							      tempfile2);
							for (tel2 = 0;
							     isspace
							     (buffer2
							      [tel2]);
							     tel2++);
							p = strrchr
							    (buffer2,
							     '\n');
							if (p)
								*p = '\0';
							description =
							    malloc((strlen
								    (&buffer2
								     [tel2])
								    +
								    40) *
								   sizeof
								   (char));
							strcpy(description,
							       &buffer2
							       [tel2]);
							conv_char
							    (description);
						}
					}
				}
				//starttijd
				if (strstr(buffer, "event-genre")) {
					fgets(buffer, 1023, tempfile);
					p = &buffer[0];
					while (isspace(*p))
						p++;
					p[strlen(p) - 1] = '\0';
					strcpy(genre, p);
					convert_genre(genre);
				}
			}
			tel++;
		}
/***************************/
/*
				if (tocache) {
					fprintf(cachetmp, "1%s-%s%s%s",
						kanaal->id, datjaar,
						datmaand, datdag);
					fprintf(cachetmp,
						" <programme start=\"%s +0%d00\" stop=\"%s +0%d00\" channel=\"%s.upclive.nl\">\n",
						progstart, tzone, progstop,
						tzone2, kanaal->id);
					fprintf(cachetmp,
						"   <title lang=\"nl\">%s</title>\n",
						titel);
					fprintf(cachetmp,
						"   <desc lang=\"nl\">%s\n",
						description);
					fprintf(cachetmp, "   </desc>\n");
					fprintf(cachetmp,
						"   <category>%s</category>\n",
						genre);
					if (date[0] != '\0')
						printf
						    ("   <date>%s</date>\n",
						     date);
					if (stars[0] != '\0')
						fprintf(cachetmp,
							"   <star-rating>\n    <value>%s/10</value>\n   </star-rating>\n",
							stars);
					fprintf(cachetmp,
						" </programme>\n");
					fprintf(cachetmp, "\n");
				}
*/
	}
	//de laatste ook meepakken zonder stoptijd.
	if (tel) {
		pthread_mutex_lock(&mymutex);
		aantalprog++;
		printf
		    ("<programme start=\"%s +0%d00\" channel=\"%s.upclive.nl\">\n",
		     progstart, tzone, kanaal->id);
		printf("   <title lang=\"nl\">%s</title>\n", titel);
		if (description) {
			printf("   <desc lang=\"nl\">%s\n", description);
			printf("   </desc>\n");
			free(description);
		}
		printf("   <category>%s</category>\n", genre);
		if (date[0] != '\0')
			printf("   <date>%s</date>\n", date);
		if (stars[0] != '\0')
			printf
			    ("   <star-rating>\n    <value>%s/10</value>\n   </star-rating>\n",
			     stars);
		printf(" </programme>\n");
		fflush(NULL);
		pthread_mutex_unlock(&mymutex);
	}
	fclose(tempfile);
	unlink(template);
	fclose(tempfile2);
	unlink(template2);
	//fprintf(stderr,"tt '%s'\n",template);
	curl_easy_cleanup(handle);
	return (1);
}
